package com.kk.xhr.model.service.impl;

import com.kk.xhr.common.pojo.BinaryEnum;
import com.kk.xhr.model.assembler.NotificationStructKit;
import com.kk.xhr.model.dao.NotificationDynamicSqlSupport;
import com.kk.xhr.model.dao.NotificationMapper;
import com.kk.xhr.model.dto.NotificationDTO;
import com.kk.xhr.model.entity.Notification;
import com.kk.xhr.model.service.INotificationService;
import lombok.RequiredArgsConstructor;
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static org.mybatis.dynamic.sql.SqlBuilder.insertMultiple;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isIn;

/**
 * 通知服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/3
 * @since 1.0.0
 */
@Repository
@RequiredArgsConstructor
public class INotificationServiceImpl implements INotificationService {
    private final NotificationMapper notificationMapper;
    private final NotificationStructKit instance = NotificationStructKit.INSTANCE;

    @Override
    public boolean add(NotificationDTO dto) {
        return 1 == notificationMapper.insertSelective(instance.toEntity(dto));
    }

    @Override
    public List<NotificationDTO> query(Long userId) {
        return notificationMapper.select(dsl -> dsl
            .where(NotificationDynamicSqlSupport.userId, isEqualTo(userId))
            .orderBy(NotificationDynamicSqlSupport.id.descending()))
            .stream()
            .map(instance::toDto)
            .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchAdd(Collection<Long> userIds, String content) {
        if (CollectionUtils.isEmpty(userIds)) {
            return;
        }
        List<Notification> notifications = userIds.stream()
            .map(userId -> new Notification().withUserId(userId).withMessage(content))
            .collect(Collectors.toList());
        MultiRowInsertStatementProvider<Notification> provider = insertMultiple(notifications)
            .into(NotificationDynamicSqlSupport.notification)
            .map(NotificationDynamicSqlSupport.userId).toProperty("userId")
            .map(NotificationDynamicSqlSupport.message).toProperty("message")
            .build().render(RenderingStrategies.MYBATIS3);
        notificationMapper.insertMultiple(provider);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(Collection<Long> ids, BinaryEnum status) {
        if (null == status || CollectionUtils.isEmpty(ids)) {
            return;
        }
        notificationMapper.update(dsl -> dsl
            .set(NotificationDynamicSqlSupport.status).equalTo(status.getValue())
            .where(NotificationDynamicSqlSupport.id, isIn(ids)));
    }
}
